// @Description 将路由相关功能提取, 方便扩展
// @Author insight21
// @Since 2021/9/11

package web

import (
	"log"
	"net/http"
	"strings"
)

type router struct {
	handlers map[string]HandlerFunc
	roots    map[string]*node
}

func NewRouter() *router {
	return &router{
		handlers: make(map[string]HandlerFunc),
		roots:    make(map[string]*node),
	}
}

// 添加路由
func (r *router) addRoute(method string, path string, handler HandlerFunc) {
	log.Printf("Route %4s - %s", method, path)
	parts := parsePattern(path)
	key := method + "-" + path

	_, ok := r.roots[method]
	// 不存在则创建
	if !ok {
		r.roots[method] = &node{}
	}

	r.roots[method].insert(path, parts, 0)
	r.handlers[key] = handler
}

// 查询路由表
func (r *router) getRoute(method, path string) (*node, map[string]string) {
	parts := parsePattern(path)
	params := make(map[string]string)

	root, ok := r.roots[method]
	if !ok {
		return nil, nil
	}

	n := root.search(parts, 0)
	if n == nil {
		return nil, nil
	}

	searchParts := parsePattern(n.pattern)
	for i, part := range searchParts {
		if part[0] == ':' {
			params[part[1:]] = parts[i]
		}
		if part[0] == '*' && len(part) > 1 {
			params[part[1:]] = strings.Join(parts[i:], "/")
			break
		}
	}

	return n, params
}

// 解析路径
func parsePattern(pattern string) []string {
	parts := strings.Split(pattern, "/")
	ret := make([]string, 0)

	for _, part := range parts {
		if part != "" {
			ret = append(ret, part)
			if part[0] == '*' {
				break
			}
		}
	}

	return ret
}

// 请求处理函数
func (r *router) handle(c *Context) {
	n, params := r.getRoute(c.Method, c.Path)
	if n == nil {
		c.midHandler = append(c.midHandler, func(c *Context) {
			c.String(http.StatusNotFound, "404 NOT FOUND: %s\n", c.Path)
		})
		c.Next()
		return
	}

	c.Params = params
	key := c.Method + "-" + n.pattern
	c.midHandler = append(c.midHandler, r.handlers[key])
	c.Next()
}
